<template>
    <!-- 动态表单 -->
    <div
        class="base-form"
        :style="`height:${formConfig.height ? formConfig.height : 'auto'}`"
    >
        <el-form
            ref="baseForm"
            :size="formConfig.size | setSize(formConfig.size)"
            :label-width="formConfig.labelWidth"
            :label-position="formConfig.labelPosition || 'right'"
            :label-suffix="formConfig.labelSuffix || ''"
            :hide-required-asterisk="formConfig.hideRequiredAsterisk || false"
            :show-message="formConfig.showMessage || true"
            :inline-message="formConfig.inlineMessage || false"
            :status-icon="formConfig.statusIcon || false"
            :validate-on-rule-change="formConfig.validateOnRuleChange || false"
            :disabled="formConfig.disabled || false"
            :rules="formRules"
            :model="formData"
            :style="`height:${formConfig.height ? formConfig.height : 'auto'}`"
        >
            <div v-for="(item, index) in formItems" :key="index" class="row">
                <div
                    class="col"
                    v-for="(childItem, index) in item"
                    :key="index"
                    :class="childItem.width || 'auto'"
                    v-show="
                        typeof childItem.isShow === 'undefined' ||
                        childItem.isShow
                            ? true
                            : false
                    "
                >
                    <template v-if="childItem.ltype === 'custom'">
                        <slot
                            :name="[childItem.slotName]"
                            :childItem="childItem"
                        ></slot>
                    </template>
                    <template v-else>
                        <component
                            :is="getComponent(childItem.ltype)"
                            :item="childItem"
                            :formData="formData"
                        />
                    </template>
                </div>
            </div>
        </el-form>
    </div>
</template>
<script>
import mixin from './mixins/index'
export default {
    name: 'baseForm',
    mixins: [mixin],
    props: {
        /**
         * 表单项配置项
         * @type Array
         */
        formItems: {
            type: Array,
            default: () => []
        },
        /**
         * 绑定的表单值
         * @type Object
         */
        formData: {
            type: Object,
            default: () => ({})
        },
        /**
         * 表单规则项
         * @type Object
         */
        formRules: {
            type: Object,
            default: () => ({})
        },
        /**
         * 表单配置项
         * @type Object
         */
        formConfig: {
            type: Object,
            default: () => ({
                /**
                 * 表单控件尺寸
                 * @type String
                 * @value medium / small / mini
                 * @Default medium
                 */

                size: '',
                /**
                 * 表单lable的宽度
                 * @type String
                 * @value
                 * @default '70px'
                 */

                labelWidth: 'auto',
                /**
                 * 表单lable的对齐方式
                 * @type String
                 * @value right/left
                 * @default 'right'
                 */

                labelPosition: 'right',
                /**
                 * 表单域标签的后缀
                 * @type String
                 * @value
                 * @default ''
                 */

                labelSuffix: '',
                /**
                 * 是否隐藏必填字段的标签旁边的红色星号
                 * @type Boolean
                 * @value true/false
                 * @default false
                 */

                hideRequiredAsterisk: false,
                /**
                 * 是否显示校验错误信息
                 * @type Boolean
                 * @value true/false
                 * @default true
                 */

                showMessage: true,
                /**
                 * 是否以行内形式展示校验信息
                 * @type Boolean
                 * @value true/false
                 * @default true
                 */

                inlineMessage: false,
                /**
                 * 是否在输入框中显示校验结果反馈图标
                 * @type Boolean
                 * @value true/false
                 * @default false
                 */

                statusIcon: false,
                /**
                 * 是否在 rules 属性改变后立即触发一次验证
                 * @type Boolean
                 * @value true/false
                 * @default false
                 */

                validateOnRuleChange: false,
                /**
                 * 是否禁用该表单内的所有组件。若设置为 true，则表单内组件上的 disabled 属性不再生效
                 * @type Boolean
                 * @value true/false
                 * @default false
                 */

                disabled: false,
                /**
                 * 表单的高度
                 */
                height: 'auto'
            })
        }
    },
    created() {
        this.setComponentSize()
    },
    methods: {
        /**
         * 设置子项的尺寸
         * 这里是为了通过外层表单的尺寸控制内层子项的尺寸
         */
        setComponentSize() {
            this.formItems.forEach(ele => {
                ele.forEach(childEle => {
                    if (this.formConfig.size || this.size) {
                        this.$set(
                            childEle,
                            'size',
                            this.formConfig.size || this.size
                        )
                    }
                })
            })
        },
        /**
         * 动态获取子表单项
         * @param {String} type
         */
        getComponent(type) {
            return require('./components/' + type + '.vue').default
        },
        /**
         * 提交表单
         * @param {Function} callback
         */
        submitForm(callback) {
            this.$refs['baseForm'].validate(valid => {
                if (valid) {
                    callback(this.formData)
                } else {
                    return false
                }
            })
        },
        /**
         * 重置表单
         */
        resetForm() {
            this.$refs['baseForm'].resetFields()
        },
        /**
         * 修改配置表单项的值
         * @param {Array} items 所有配置项列表
         * @param {String} prop 配置项的唯一key值
         * @param {*} props
         */
        setFormItemProp(prop, key, value) {
            if (Array.isArray(this.formItems) && this.formItems.length) {
                for (let i = 0; i < this.formItems.length; i++) {
                    const element = this.formItems[i]
                    element.forEach(v => {
                        if (v.prop === prop) {
                            v[key] = value
                        }
                    })
                }
            } else {
                return
            }
        }
    }
}
</script>
<style lang="scss">
.el-form-item__content {
    display: flex;
    align-items: center;
}
</style>
<style lang="scss" scoped>
.base-form {
    @include box_flex(
        $width: 100%,
        $height: 100%,
        $direction: row,
        $justify: flex-start,
        $align: flex-start
    );
}
</style>
